home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / MoreNetworkSetup / NetworkSetup / MoreNetworkSetup.c next >
Encoding:
Text File  |  2000-09-28  |  14.8 KB  |  589 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MoreNetworkSetup.c
  3.  
  4.     Contains:    Simple wrappers to make Network Setup easier.
  5.  
  6.     Written by:    Quinn
  7.  
  8.     Copyright:    Copyright © 1998 by Apple Computer, Inc., all rights reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.  
  20.         <12>     17/1/00    Quinn   Updates for latest Network Setup headers.
  21.         <11>    19/10/99    Quinn   Fix embarrassing spelling error.
  22.         <10>     16/9/99    Quinn   MNGetPrefHandle was always returning an error.  Thanks to Thomas
  23.                                     Weisbach.
  24.          <9>     31/8/99    AndyB   MNSGetEntitiesList could lose MemError when allocating paramInfos.
  25.          <8>     21/4/99    Quinn   Added MNSGetPrefHandle, MNSSetPrefHandle and MNSIterateEntity,
  26.                                     along with some general tidy up.
  27.          <7>     30/3/99    Quinn   Fixed type check error when calling DisposePtr.
  28.          <6>    10/11/98    Quinn   Fix bug in MNSIterateSet where it incremented the loop counter
  29.                                     twice each iteration. Whoops.
  30.          <5>    10/11/98    Quinn   Convert "MorePrefix.h" to "MoreSetup.h".
  31.          <4>     5/11/98    Quinn   Use MoreAssertQ instead of MoreAssert.
  32.          <3>     5/11/98    Quinn   Fix header again.
  33.          <2>     5/11/98    Quinn   Fix header.
  34.          <1>     5/11/98    Quinn   First checked in.
  35. */
  36.  
  37. /////////////////////////////////////////////////////////////////
  38. // MoreIsBetter Setup
  39.  
  40. #include "MoreSetup.h"
  41.  
  42. /////////////////////////////////////////////////////////////////
  43. // Mac OS Interfaces
  44.  
  45. #include <Types.h>
  46. #include <Files.h>
  47. #include <Errors.h>
  48. #include <Folders.h>
  49. #include <Resources.h>
  50. #include <Gestalt.h>
  51. #include <CodeFragments.h>
  52. #include <NetworkSetup.h>
  53.  
  54. /////////////////////////////////////////////////////////////////
  55. // Our Prototypes
  56.  
  57. #include "MoreNetworkSetup.h"
  58.  
  59. /////////////////////////////////////////////////////////////////
  60.  
  61. #if TARGET_RT_MAC_CFM
  62.  
  63.     extern pascal Boolean IsNetworkSetupAvailable()
  64.         // See comment in interface part.
  65.     {
  66.         return (void *) OTCfgOpenDatabase != (void *) kUnresolvedCFragSymbolAddress;
  67.     }
  68.  
  69. #else
  70.  
  71.     extern pascal Boolean IsNetworkSetupAvailable()
  72.         // See comment in interface part.
  73.     {
  74.         OSStatus junk;
  75.         Boolean result;
  76.         UInt32  response;
  77.         CFragConnectionID connID;
  78.         Ptr junkMain;
  79.         Str255 junkMessage;
  80.         
  81.         #if TARGET_RT_MAC_CFM
  82.             #error "IsNetworkSetupAvailable: This routine should not be used by CFM code."
  83.         #endif
  84.         
  85.         result = false;
  86.         
  87.         if ( Gestalt(gestaltCFMAttr, (SInt32 *) &response) == noErr && (response & (1 << gestaltCFMPresent)) != 0) {
  88.             if ( GetSharedLibrary("\pCfgOpenTpt", kAnyCFragArch, kReferenceCFrag, &connID, &junkMain, junkMessage) == noErr ) {
  89.                 result = true;
  90.                 junk = CloseConnection(&connID);
  91.                 MoreAssertQ(junk == noErr);
  92.             }
  93.         }
  94.         
  95.         return result;
  96.     }
  97.  
  98. #endif
  99.  
  100. extern pascal Boolean  MNSValidDatabase(const MNSDatabaseRef *ref)
  101.     // See comment in interface part.
  102. {
  103.     return ref != nil && ref->dbRef != nil && ref->area != 0;
  104. }
  105.  
  106. extern pascal Boolean  MNSDatabaseWritable(const MNSDatabaseRef *ref)
  107.     // See comment in interface part.
  108. {
  109.     return (ref->originalArea != 0);
  110. }
  111.  
  112. extern pascal OSStatus MNSOpenDatabase(MNSDatabaseRef *ref, Boolean forWriting)
  113.     // See comment in interface part.
  114. {
  115.     OSStatus err;
  116.     OSStatus junk;
  117.  
  118.     MoreAssertQ(ref != nil);
  119.     
  120.     ref->dbRef = nil;
  121.     ref->area = 0;
  122.     ref->originalArea = 0;
  123.     
  124.     err = OTCfgOpenDatabase(&ref->dbRef);
  125.     if (err == noErr) {
  126.         err = OTCfgGetCurrentArea(ref->dbRef, &ref->area);
  127.         if (err == noErr) {
  128.             if (forWriting) {
  129.                 ref->originalArea = ref->area;
  130.                 err = OTCfgBeginAreaModifications(ref->dbRef, ref->originalArea, &ref->area);
  131.             } else {
  132.                 err = OTCfgOpenArea(ref->dbRef, ref->area);
  133.             }
  134.         }
  135.         if (err != noErr) {
  136.             junk = MNSCloseDatabase(ref, false);
  137.             MoreAssertQ(junk == noErr);
  138.         }
  139.     }
  140.     return err;    
  141. }
  142.  
  143. extern pascal OSStatus MNSCloseDatabase(MNSDatabaseRef *ref, Boolean commit)
  144.     // See comment in interface part.
  145. {
  146.     OSStatus err;
  147.     OSStatus err2;
  148.     
  149.     MoreAssertQ(ref != nil);
  150.     MoreAssertQ(ref->dbRef != nil);
  151.     MoreAssertQ(ref->originalArea == 0 || ref->area != 0);
  152.  
  153.     err = noErr;
  154.     if (ref->area != 0) {
  155.         if ( MNSDatabaseWritable(ref) ) {
  156.             if ( commit ) {
  157.                 err = OTCfgCommitAreaModifications(ref->dbRef, ref->originalArea, ref->area);
  158.             } else {
  159.                 err = OTCfgAbortAreaModifications(ref->dbRef, ref->originalArea);
  160.             }
  161.         } else {
  162.             // Database was opened read-only, you're just not allowed to commit it.
  163.             MoreAssertQ( ! commit );
  164.             err = OTCfgCloseArea(ref->dbRef, ref->area);
  165.         }
  166.     }
  167.     err2 = OTCfgCloseDatabase(&ref->dbRef);
  168.     if (err == noErr) {
  169.         err = err2;
  170.     }
  171.     ref->dbRef = nil;
  172.     ref->area = 0;
  173.     ref->originalArea = 0;
  174.  
  175.     return err;
  176. }
  177.  
  178. extern pascal OSStatus MNSGetFixedSizePref(const MNSDatabaseRef *ref,
  179.                         const CfgEntityRef *entityID,
  180.                         OSType prefType,
  181.                         void *buffer, ByteCount prefSize)
  182.     // See comment in interface part.
  183. {
  184.     OSStatus err;
  185.     OSStatus err2;
  186.     CfgEntityAccessID prefsRefNum;
  187.     ByteCount actualPrefSize;
  188.  
  189.     MoreAssertQ(MNSValidDatabase(ref));
  190.     MoreAssertQ(entityID != nil);
  191.     MoreAssertQ(buffer != nil);
  192.     
  193.     // Open the entity, read out the preference, and then
  194.     // close it down.
  195.     
  196.     err = OTCfgOpenPrefs(ref->dbRef, entityID, false, &prefsRefNum);
  197.     if (err == noErr) {
  198.         err = OTCfgGetPrefsSize(prefsRefNum, prefType, &actualPrefSize);
  199.         if (err == noErr && actualPrefSize != prefSize) {
  200.             err = -1;
  201.         }
  202.         if (err == noErr) {
  203.             err = OTCfgGetPrefs(prefsRefNum, prefType, buffer, prefSize);
  204.         }
  205.     
  206.         err2 = OTCfgClosePrefs(prefsRefNum);
  207.         if (err == noErr) {
  208.             err = err2;
  209.         }
  210.     }
  211.     
  212.     return err;
  213. }
  214.  
  215. extern pascal OSStatus MNSGetPref(const MNSDatabaseRef *ref,
  216.                         const CfgEntityRef *entityID,
  217.                         OSType prefType,
  218.                         void **buffer, ByteCount *prefSize)
  219.     // See comment in interface part.
  220. {
  221.     OSStatus err;
  222.     OSStatus err2;
  223.     CfgEntityAccessID prefsRefNum;
  224.     ByteCount junkPrefSize;
  225.  
  226.     MoreAssertQ(MNSValidDatabase(ref));
  227.     MoreAssertQ(entityID != nil);
  228.     MoreAssertQ(buffer != nil);
  229.     MoreAssertQ(*buffer == nil);
  230.     
  231.     if (prefSize == nil) {
  232.         prefSize = &junkPrefSize;
  233.     }
  234.  
  235.     // Open the entity, read out the preference, and then
  236.     // close it down.
  237.     
  238.     *buffer = nil;    
  239.     err = OTCfgOpenPrefs(ref->dbRef, entityID, false, &prefsRefNum);
  240.     if (err == noErr) {
  241.         err = OTCfgGetPrefsSize(prefsRefNum, prefType, prefSize);
  242.  
  243.         if (err == noErr) {
  244.             *buffer = NewPtr(*prefSize);
  245.             if (*buffer == nil) {
  246.                 MoreAssertQ(err == memFullErr);
  247.                 err = memFullErr;
  248.             }
  249.         }
  250.         if (err == noErr) {
  251.             err = OTCfgGetPrefs(prefsRefNum, prefType, *buffer, *prefSize);
  252.         }
  253.     
  254.         err2 = OTCfgClosePrefs(prefsRefNum);
  255.         if (err == noErr) {
  256.             err = err2;
  257.         }
  258.     }
  259.     
  260.     // Clean up.
  261.     
  262.     if (err != noErr && *buffer != nil) {
  263.         DisposePtr( (Ptr) *buffer);
  264.         MoreAssertQ(MemError() == noErr);
  265.         *buffer = nil;
  266.     }
  267.     return err;
  268. }
  269.  
  270. extern pascal OSStatus MNSSetPref(const MNSDatabaseRef *ref,
  271.                         const CfgEntityRef *entityID,
  272.                         OSType prefType,
  273.                         const void *prefData, ByteCount prefSize)
  274.     // See comment in interface part.
  275. {
  276.     OSStatus err;
  277.     OSStatus err2;
  278.     CfgEntityAccessID prefsRefNum;
  279.  
  280.     MoreAssertQ(MNSValidDatabase(ref));
  281.     MoreAssertQ(MNSDatabaseWritable(ref));
  282.     MoreAssertQ(entityID != nil);
  283.     MoreAssertQ(prefData != nil);
  284.     MoreAssertQ(prefSize != nil);
  285.  
  286.     err = OTCfgOpenPrefs(ref->dbRef, entityID, true, &prefsRefNum);
  287.     if (err == noErr) {
  288.         err = OTCfgSetPrefs(prefsRefNum,  prefType, prefData, prefSize);
  289.     
  290.         err2 = OTCfgClosePrefs(prefsRefNum);
  291.         if (err == noErr) {
  292.             err = err2;
  293.         }
  294.     }
  295.     
  296.     return err;
  297. }
  298.  
  299. extern pascal OSStatus MNSGetPrefHandle(const MNSDatabaseRef *ref,
  300.                         const CfgEntityRef *entityID,
  301.                         OSType prefType,
  302.                         Handle prefData)
  303.     // See comment in interface part.
  304. {
  305.     OSStatus err;
  306.     OSStatus err2;
  307.     CfgEntityAccessID prefsRefNum;
  308.     ByteCount prefSize;
  309.     SInt8 s;
  310.  
  311.     MoreAssertQ(MNSValidDatabase(ref));
  312.     MoreAssertQ(entityID != nil);
  313.     MoreAssertQ(prefData != nil);
  314.     
  315.     // Open the entity, read out the preference, and then
  316.     // close it down.
  317.     
  318.     err = OTCfgOpenPrefs(ref->dbRef, entityID, false, &prefsRefNum);
  319.     if (err == noErr) {
  320.         err = OTCfgGetPrefsSize(prefsRefNum, prefType, &prefSize);
  321.         if (err == noErr) {
  322.             SetHandleSize(prefData, prefSize);
  323.             err = MemError();
  324.         }
  325.         if (err == noErr) {
  326.             s = HGetState(prefData);
  327.             HLock(prefData);
  328.             err = OTCfgGetPrefs(prefsRefNum, prefType, *prefData, prefSize);
  329.             HSetState(prefData, s);
  330.         }
  331.     
  332.         err2 = OTCfgClosePrefs(prefsRefNum);
  333.         if (err == noErr) {
  334.             err = err2;
  335.         }
  336.     }
  337.     
  338.     return err;
  339. }
  340.  
  341. extern pascal OSStatus MNSSetPrefHandle(const MNSDatabaseRef *ref,
  342.                         const CfgEntityRef *entityID,
  343.                         OSType prefType,
  344.                         Handle prefData)
  345.     // See comment in interface part.
  346. {
  347.     OSStatus err;
  348.     SInt8 s;
  349.     
  350.     s = HGetState(prefData);
  351.     MoreAssertQ(MemError() == noErr);
  352.     HLock(prefData);
  353.     MoreAssertQ(MemError() == noErr);
  354.  
  355.     err = MNSSetPref(ref, entityID, prefType, *prefData, GetHandleSize(prefData));
  356.     
  357.     HSetState(prefData, s);
  358.     MoreAssertQ(MemError() == noErr);
  359.     
  360.     return err;
  361. }
  362.  
  363. extern pascal OSStatus MNSIterateEntity(const MNSDatabaseRef *ref,
  364.                                     const CfgEntityRef *entity,
  365.                                     MNSPrefIterator iteratorProc,
  366.                                     void *refcon)
  367.     // See comment in interface part.
  368. {
  369.     OSStatus err;
  370.     OSStatus err2;
  371.     CfgEntityAccessID prefsRefNum;
  372.     ItemCount prefsTOCCount;
  373.     CfgPrefsHeader *prefsTOCs;
  374.     ItemCount prefsTOCIndex;
  375.     OSType prefType;
  376.     Handle prefDataH;
  377.     ByteCount prefSize;
  378.     
  379.     prefsTOCs = nil;
  380.     prefDataH = nil;
  381.     
  382.     prefDataH = NewHandle(0);
  383.     err = MemError();
  384.     if (err == noErr) {
  385.         err = OTCfgOpenPrefs(ref->dbRef, entity, false, &prefsRefNum);
  386.         if (err == noErr) {
  387.             err = OTCfgGetPrefsTOCCount(prefsRefNum, &prefsTOCCount);
  388.             if (err == noErr) {
  389.                 prefsTOCs = (CfgPrefsHeader *) NewPtr( prefsTOCCount * sizeof(CfgPrefsHeader));
  390.                 err = MemError();
  391.             }
  392.             if (err == noErr) {
  393.                 err = OTCfgGetPrefsTOC(prefsRefNum, &prefsTOCCount, prefsTOCs);
  394.             }
  395.             if (err == noErr) {    
  396.                 for (prefsTOCIndex = 0; prefsTOCIndex < prefsTOCCount; prefsTOCIndex++) {
  397.                     prefType = prefsTOCs[prefsTOCIndex].fType;
  398.                     prefSize = prefsTOCs[prefsTOCIndex].fSize;
  399.                     HUnlock(prefDataH);
  400.                     MoreAssertQ(MemError() == noErr);
  401.                     
  402.                     SetHandleSize(prefDataH, prefSize);
  403.                     err = MemError();
  404.                     if (err == noErr) {
  405.                         HLock(prefDataH);
  406.                         MoreAssertQ(MemError() == noErr);
  407.  
  408.                         err = OTCfgGetPrefs(prefsRefNum, prefType, *prefDataH, prefSize);
  409.                     }
  410.                     if (err == noErr) {
  411.                         iteratorProc(prefType, *prefDataH, prefSize, refcon);
  412.                     }
  413.                     if (err != noErr) {
  414.                         break;
  415.                     }
  416.                 }
  417.             }
  418.             
  419.             err2 = OTCfgClosePrefs(prefsRefNum);
  420.             if (err == noErr) {
  421.                 err = err2;
  422.             }
  423.         }
  424.     }
  425.     
  426.     if (prefsTOCs != nil) {
  427.         DisposePtr( (Ptr) prefsTOCs);
  428.         MoreAssertQ(MemError() == noErr);
  429.     }
  430.     if (prefDataH != nil) {
  431.         DisposeHandle(prefDataH);
  432.         MoreAssertQ(MemError() == noErr);
  433.     }
  434.     
  435.     return err;
  436. }
  437.  
  438.  
  439. extern pascal OSStatus MNSGetEntitiesList(const MNSDatabaseRef *ref,
  440.                                 OSType entityClass, OSType entityType,
  441.                                 ItemCount *entityCount,
  442.                                 CfgEntityRef **entityIDs,
  443.                                 CfgEntityInfo **entityInfos)
  444.     // See comment in interface part.
  445. {
  446.     OSStatus err;
  447.     CfgEntityRef *paramIDs;
  448.     CfgEntityInfo *paramInfos;
  449.  
  450.     MoreAssertQ(MNSValidDatabase(ref));
  451.     MoreAssertQ(entityCount != nil);
  452.     MoreAssertQ(entityIDs == nil   || *entityIDs == nil  );
  453.     MoreAssertQ(entityInfos == nil || *entityInfos == nil);
  454.  
  455.     err = OTCfgGetEntitiesCount(ref->dbRef, ref->area, entityClass, entityType, entityCount);
  456.     if (err == noErr) {
  457.         if (entityIDs == nil) {
  458.             paramIDs = nil;
  459.         } else {
  460.             *entityIDs = (CfgEntityRef *) NewPtr(*entityCount * sizeof(CfgEntityRef));
  461.             if (*entityIDs == nil) {
  462.                 MoreAssertQ(err == memFullErr);
  463.                 err = memFullErr;
  464.             }
  465.             paramIDs = *entityIDs;
  466.         }
  467.     }
  468.     if (err == noErr) {
  469.         if (entityInfos == nil) {
  470.             paramInfos = nil;
  471.         } else {
  472.             *entityInfos = (CfgEntityInfo *) NewPtr(*entityCount * sizeof(CfgEntityInfo));
  473.             if (*entityInfos == nil) {
  474.                 MoreAssertQ(err == memFullErr);
  475.                 err = memFullErr;
  476.             }
  477.             paramInfos = *entityInfos;
  478.         }
  479.     }
  480.     if (err == noErr) {
  481.         err = OTCfgGetEntitiesList(ref->dbRef, ref->area, 
  482.                     entityClass, entityType, 
  483.                     entityCount, paramIDs, paramInfos);
  484.     }
  485.     
  486.     // Clean up.
  487.     
  488.     if (err != noErr) {
  489.         if (*entityIDs != nil) {
  490.             DisposePtr( (Ptr) *entityIDs);
  491.             MoreAssertQ(MemError() == noErr);
  492.             *entityIDs = nil;
  493.         }
  494.         if (*entityInfos != nil) {
  495.             DisposePtr( (Ptr) *entityInfos);
  496.             MoreAssertQ(MemError() == noErr);
  497.             *entityInfos = nil;
  498.         }
  499.     }
  500.  
  501.     return err;
  502. }
  503.  
  504. extern pascal OSStatus MNSFindActiveSet(const MNSDatabaseRef *ref, CfgEntityRef *activeSet)
  505.     // See comment in interface part.
  506. {
  507.     OSStatus err;
  508.     ItemCount setCount;
  509.     CfgEntityRef *setEntities;
  510.     Boolean found;
  511.     ItemCount thisSetIndex;
  512.     CfgSetsStruct thisStruct;
  513.  
  514.     MoreAssertQ(MNSValidDatabase(ref));
  515.     MoreAssertQ(activeSet != nil);
  516.     
  517.     setEntities = nil;
  518.  
  519.     err = MNSGetEntitiesList(ref, kOTCfgClassSetOfSettings, kOTCfgTypeSetOfSettings, &setCount, &setEntities, nil);
  520.     if (err == noErr) {
  521.         thisSetIndex = 0;
  522.         found = false;
  523.         while (err == noErr && thisSetIndex < setCount && ! found) {
  524.             err = MNSGetFixedSizePref(ref, &setEntities[thisSetIndex], kOTCfgSetsStructPref,
  525.                             &thisStruct, sizeof(thisStruct));
  526.             if (err == noErr) {
  527.                 found = ((thisStruct.fFlags & kOTCfgSetsFlagActiveMask) != 0);
  528.                 if ( ! found ) {
  529.                     thisSetIndex += 1;
  530.                 }
  531.             }
  532.         }
  533.         if (err == noErr && ! found) {
  534.             err = -2;
  535.         }
  536.     }
  537.     if (err == noErr) {
  538.         *activeSet = setEntities[thisSetIndex];
  539.     }
  540.  
  541.     // Clean up.
  542.     
  543.     if (setEntities != nil) {
  544.         DisposePtr( (Ptr) setEntities);
  545.         MoreAssertQ(MemError() == noErr);
  546.     }
  547.     
  548.     return err;
  549. }
  550.  
  551. extern pascal OSStatus MNSIterateSet(const MNSDatabaseRef *ref,
  552.                                     const CfgEntityRef *setEntity,
  553.                                     MNSSetIterator iteratorProc,
  554.                                     void *refcon,
  555.                                     Boolean writeAfterIterate)
  556.     // See comment in interface part.
  557. {
  558.     OSStatus err;
  559.     CfgSetsVector *vectorPrefData;
  560.     ByteCount vectorPrefSize;
  561.     ItemCount thisElementIndex;
  562.  
  563.     MoreAssertQ(MNSValidDatabase(ref));
  564.     MoreAssertQ( !writeAfterIterate || MNSDatabaseWritable(ref) );
  565.     MoreAssertQ(setEntity != nil);
  566.     MoreAssertQ(iteratorProc != nil);
  567.     
  568.     vectorPrefData = nil;
  569.  
  570.     err = MNSGetPref(ref, setEntity, kOTCfgSetsVectorPref,
  571.                     &vectorPrefData, &vectorPrefSize);
  572.     if (err == noErr) {
  573.         for (thisElementIndex = 0; thisElementIndex < vectorPrefData->fCount; thisElementIndex++) {
  574.             iteratorProc(ref, &vectorPrefData->fElements[thisElementIndex], refcon);
  575.         }
  576.         if (writeAfterIterate) {
  577.             err = MNSSetPref(ref, setEntity, kOTCfgSetsVectorPref, vectorPrefData, vectorPrefSize);
  578.         }
  579.     }
  580.     
  581.     // Clean up.
  582.     
  583.     if (vectorPrefData != nil) {
  584.         DisposePtr( (Ptr) vectorPrefData);
  585.         MoreAssertQ(MemError() == noErr);
  586.     }
  587.     return err;
  588. }
  589.